package com.autumn.platform.core.exception;

import java.util.Locale;

import org.springframework.context.NoSuchMessageException;

import com.autumn.platform.core.context.track.Tracker;
import com.autumn.platform.core.spring.SpringHolder;

public class CodableException extends RuntimeException {

    /**
     * 
     */
    private static final long serialVersionUID = -1041248074153680042L;

    private static final Object[] EMPTY_ARGS = new Object[0];

    private final String trackId;

    private final String code;

    private final Object[] args;

    /* package */ CodableException(String code, Throwable cause, Object[] args) {
        super(getLocaleMessage0(code, args, null, true), cause);
        this.code = code;
        this.args = args;
        this.trackId = Tracker.getCurrentTrackId();
    }

    /* package */ CodableException(String code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
        this.args = EMPTY_ARGS;
        this.trackId = Tracker.getCurrentTrackId();
    }

    public String getShortMessage(Locale locale) {
        return getLocaleMessage0(code, args, locale, false);
    }

    public String getMessage(Locale locale) {
        return getLocaleMessage0(code, args, locale, true);
    }

    public String getTrackId() {
        return trackId;
    }

    public String getCode() {
        return code;
    }

    public Object[] getArgs() {
        return args;
    }

    private static String getLocaleMessage0(String code, Object[] args, Locale locale, boolean addTracker) {
        if (null == code) {
            throw new IllegalArgumentException("the code of CodeExcption must not null");
        }

        try {
            String message = SpringHolder.getMessage(code, args, locale);
            if (addTracker) {
                message = Tracker.appendTrackId(message);
                if (null == message) {
                    message = "[code: " + code + "] ";
                } else {
                    message = "[code: " + code + "] " + message;
                }
            }
            return message;
        } catch (NoSuchMessageException e) {
            throw new IllegalArgumentException("the code [" + code + "] of CodeExcption is not found", e);
        }
    }
}
